#include <asm/armlocal_register.h>
#include <timer.h>
#include <io.h>
#include <type.h>
#include <sched.h>

unsigned long volatile cacheline_aligned jiffies;
static unsigned int arch_timer_rate;

/*hardware hz*/
static unsigned int generic_timer_get_freq(void)
{
	unsigned int freq;

	asm volatile(
		"mrs %0, cntfrq_el0"
		: "=r" (freq)
		:
		: "memory");

	return freq;
}

static void generic_timer_init(){
    asm volatile(
        "mov x0, #1\n"
        "msr cntp_ctl_el0, x0"
        :
        :
        : "memory"
    );
}

static void generic_timer_reset(unsigned int val){
    asm volatile(
        "msr cntp_tval_el0, %x[time_val]"
        :
        : [time_val]"r"(val)
        : "memory"
    );
}

static void enable_timer_interrupt(){
    writel(CNT_PNS_IRQ, TIMER_CNTRL0);
}

void handle_pns_irq(){
    
    generic_timer_reset(arch_timer_rate);
    //printk("timer interrupt has been received\n");
    tick_handle_periodic();
}

void timer_init(void)
{

    /*every system hz need arch_timer_rate timer hz*/
    arch_timer_rate = generic_timer_get_freq();
    printk("cntp freq: 0x%x\r\n", arch_timer_rate);
    arch_timer_rate  /= HZ;


    generic_timer_init(); //start timer
    generic_timer_reset(arch_timer_rate); //set init_val 

	gicv2_unmask_irq(GENERIC_TIMER_IRQ); 

    enable_timer_interrupt();

}